import 'dart:async';
import 'package:sqflite/sqflite.dart' as sqflite;
import 'package:froom/froom.dart';
import 'package:sqflite_common/sqlite_api.dart';

/// 事务传播行为枚举
enum TransactionPropagation {
  /// 如果当前存在事务，则加入该事务；如果不存在事务，则创建一个新事务
  required,

  /// 总是创建一个新事务，如果当前存在事务，则挂起当前事务
  requiresNew,

  /// 如果当前存在事务，则加入该事务；如果不存在事务，则以非事务方式执行
  supports,

  /// 总是以非事务方式执行，如果当前存在事务，则挂起当前事务
  notSupported,

  /// 如果当前存在事务，则抛出异常
  never,

  /// 如果当前不存在事务，则抛出异常
  mandatory,
}

/// 事务隔离级别枚举
enum TransactionIsolation {
  /// 默认隔离级别（SQLite默认为SERIALIZABLE）
  defaultLevel,

  /// 读未提交
  readUncommitted,

  /// 读已提交
  readCommitted,

  /// 可重复读
  repeatableRead,

  /// 串行化
  serializable,
}

/// 事务状态
class TransactionStatus {
  /// 事务ID
  final String id;

  /// 是否为新事务
  final bool isNewTransaction;

  /// 是否已完成
  bool _completed = false;

  /// 是否已回滚
  bool _rolledBack = false;

  /// 事务对象
  sqflite.Transaction? _transaction;

  TransactionStatus._(this.id, this.isNewTransaction);

  /// 是否已完成
  bool get isCompleted => _completed;

  /// 是否已回滚
  bool get isRolledBack => _rolledBack;

  /// 是否活跃
  bool get isActive => !_completed && !_rolledBack;

  /// 设置事务对象
  void _setTransaction(sqflite.Transaction transaction) {
    _transaction = transaction;
  }

  /// 获取事务对象
  sqflite.Transaction? get transaction => _transaction;

  /// 标记完成
  void _setCompleted() {
    _completed = true;
  }

  /// 标记回滚
  void _setRolledBack() {
    _rolledBack = true;
  }
}

/// 事务定义
class TransactionDefinition {
  /// 传播行为
  final TransactionPropagation propagation;

  /// 隔离级别
  final TransactionIsolation isolation;

  /// 超时时间（秒）
  final int timeout;

  /// 是否只读
  final bool readOnly;

  /// 事务名称
  final String? name;

  const TransactionDefinition({
    this.propagation = TransactionPropagation.required,
    this.isolation = TransactionIsolation.defaultLevel,
    this.timeout = -1,
    this.readOnly = false,
    this.name,
  });
}

/// 事务回调接口
abstract class TransactionCallback<T> {
  /// 在事务中执行的操作
  Future<T> doInTransaction(TransactionStatus status);
}

/// 事务管理器
class TransactionManager {
  static TransactionManager? _instance;

  /// Froom数据库实例映射
  final Map<String, FroomDatabase> _froomDatabases = {};

  /// 默认数据库名称
  static String? _defaultDatabaseName;

  /// Zone-local 存储键，用于事务栈隔离
  static const Symbol _transactionStackKey = #fallDataTransactionStack;

  TransactionManager._internal();

  /// 获取单例实例
  static TransactionManager get instance {
    _instance ??= TransactionManager._internal();
    return _instance!;
  }

  /// 注册Froom数据库
  void registerDatabase(String name, FroomDatabase database,
      {bool isDefault = false}) {
    _froomDatabases[name] = database;
    if (isDefault) {
      _defaultDatabaseName = name;
    }
  }

  /// 获取Froom数据库
  FroomDatabase? getFroomDatabase([String? databaseName]) {
    final name = databaseName ?? _defaultDatabaseName;
    return name != null ? _froomDatabases[name] : null;
  }

  /// 获取默认数据库名称
  static String? getDefaultDatabaseName() {
    return _defaultDatabaseName;
  }

  /// 设置默认数据库
  void setDefaultDatabase(String databaseName) {
    if (_froomDatabases.containsKey(databaseName)) {
      _defaultDatabaseName = databaseName;
    } else {
      throw StateError('数据库 $databaseName 未注册');
    }
  }

  /// 检查是否为默认数据库
  bool isDefaultDatabase(String databaseName) {
    return _defaultDatabaseName == databaseName;
  }

  /// 获取底层SQLite数据库
  DatabaseExecutor? getSQLiteDatabase([String? databaseName]) {
    final froomDb = getFroomDatabase(databaseName);
    return froomDb?.database;
  }

  /// 关闭数据库并清理资源
  Future<void> closeDatabase([String? databaseName]) async {
    final name = databaseName ?? _defaultDatabaseName;
    if (name != null) {
      final froomDb = _froomDatabases[name];
      if (froomDb != null) {
        await froomDb.close();
        _froomDatabases.remove(name);

        // 如果关闭的是默认数据库，清理默认设置
        if (_defaultDatabaseName == name) {
          _defaultDatabaseName = null;
        }
      }
    }
  }

  /// 检查数据库是否已注册
  bool isDatabaseRegistered([String? databaseName]) {
    final name = databaseName ?? _defaultDatabaseName;
    return name != null && _froomDatabases.containsKey(name);
  }

  /// 获取当前 Zone 的事务栈
  List<TransactionStatus> _getTransactionStack() {
    return Zone.current[_transactionStackKey] as List<TransactionStatus>? ??
        <TransactionStatus>[];
  }

  /// 设置当前 Zone 的事务栈
  void _setTransactionStack(List<TransactionStatus> stack) {
    (Zone.current as dynamic)[_transactionStackKey] = stack;
  }

  /// 执行事务 - 基于Froom数据库
  Future<T> execute<T>(
    TransactionCallback<T> callback, {
    TransactionDefinition definition = const TransactionDefinition(),
    String? databaseName,
  }) async {
    return await runZoned(() async {
      final froomDb = getFroomDatabase(databaseName);
      if (froomDb == null) {
        throw StateError(
            'Froom数据库未注册: ${databaseName ?? _defaultDatabaseName}');
      }

      final sqliteDb = froomDb.database;
      final currentTransaction = _getCurrentTransaction();

      // 处理事务传播行为
      switch (definition.propagation) {
        case TransactionPropagation.required:
          if (currentTransaction != null) {
            // 加入现有事务
            return await callback.doInTransaction(currentTransaction);
          } else {
            // 创建新事务
            return await _executeInNewFroomTransaction(
                sqliteDb, callback, definition);
          }

        case TransactionPropagation.requiresNew:
          // 总是创建新事务
          return await _executeInNewFroomTransaction(
              sqliteDb, callback, definition);

        case TransactionPropagation.supports:
          if (currentTransaction != null) {
            // 加入现有事务
            return await callback.doInTransaction(currentTransaction);
          } else {
            // 无事务执行
            return await _executeWithoutTransaction(callback);
          }

        case TransactionPropagation.notSupported:
          // 总是无事务执行
          return await _executeWithoutTransaction(callback);

        case TransactionPropagation.never:
          if (currentTransaction != null) {
            throw StateError('当前存在事务，但传播行为为NEVER');
          }
          return await _executeWithoutTransaction(callback);

        case TransactionPropagation.mandatory:
          if (currentTransaction == null) {
            throw StateError('当前不存在事务，但传播行为为MANDATORY');
          }
          return await callback.doInTransaction(currentTransaction);
      }
    }, zoneValues: {
      _transactionStackKey: _getTransactionStack(),
    });
  }

  /// 获取当前事务状态
  TransactionStatus? getCurrentTransaction() {
    return _getCurrentTransaction();
  }

  /// 是否在事务中
  bool get isInTransaction => _getCurrentTransaction() != null;

  /// 设置回滚标记
  void setRollbackOnly() {
    final current = _getCurrentTransaction();
    if (current != null) {
      current._setRolledBack();
    }
  }

  /// 在新的Froom事务中执行
  Future<T> _executeInNewFroomTransaction<T>(
    DatabaseExecutor database,
    TransactionCallback<T> callback,
    TransactionDefinition definition,
  ) async {
    final transactionId = _generateTransactionId();
    final status = TransactionStatus._(transactionId, true);
    final transactionStack = _getTransactionStack();

    try {
      transactionStack.add(status);
      _setTransactionStack(transactionStack);

      // 使用Froom底层的SQLite事务机制
      if (database is sqflite.Database) {
        return await database.transaction<T>((txn) async {
          status._setTransaction(txn);

          try {
            final result = await callback.doInTransaction(status);

            if (status.isRolledBack) {
              throw Exception('事务已标记为回滚');
            }

            status._setCompleted();
            return result;
          } catch (e) {
            status._setRolledBack();
            rethrow;
          }
        });
      } else {
        // 如果不是Database类型，直接执行回调
        try {
          final result = await callback.doInTransaction(status);

          if (status.isRolledBack) {
            throw Exception('事务已标记为回滚');
          }

          status._setCompleted();
          return result;
        } catch (e) {
          status._setRolledBack();
          rethrow;
        }
      }
    } finally {
      transactionStack.remove(status);
      _setTransactionStack(transactionStack);
    }
  }

  /// 无事务执行
  Future<T> _executeWithoutTransaction<T>(
    TransactionCallback<T> callback,
  ) async {
    final transactionId = _generateTransactionId();
    final status = TransactionStatus._(transactionId, false);

    try {
      return await callback.doInTransaction(status);
    } finally {
      status._setCompleted();
    }
  }

  /// 获取当前事务
  TransactionStatus? _getCurrentTransaction() {
    final transactionStack = _getTransactionStack();
    return transactionStack.isNotEmpty ? transactionStack.last : null;
  }

  /// 生成事务ID
  String _generateTransactionId() {
    final transactionStack = _getTransactionStack();
    return 'txn_${DateTime.now().millisecondsSinceEpoch}_${transactionStack.length}';
  }
}

/// 简化的事务执行方法
extension TransactionManagerExtension on TransactionManager {
  /// 执行简单事务（基于Froom）
  Future<T> executeTransaction<T>(
    Future<T> Function(sqflite.Transaction txn) action, {
    String? databaseName,
    TransactionDefinition definition = const TransactionDefinition(),
  }) async {
    return execute(
      _SimpleTransactionCallback(action),
      definition: definition,
      databaseName: databaseName,
    );
  }

  /// 执行只读事务
  Future<T> executeReadOnlyTransaction<T>(
    Future<T> Function(TransactionStatus status) action, {
    String? databaseName,
  }) async {
    return execute(
      _FunctionTransactionCallback(action),
      definition: const TransactionDefinition(readOnly: true),
      databaseName: databaseName,
    );
  }

  /// 执行新事务
  Future<T> executeNewTransaction<T>(
    Future<T> Function(TransactionStatus status) action, {
    String? databaseName,
  }) async {
    return execute(
      _FunctionTransactionCallback(action),
      definition: const TransactionDefinition(
        propagation: TransactionPropagation.requiresNew,
      ),
      databaseName: databaseName,
    );
  }

  /// 执行Froom事务（直接使用FroomDatabase）
  Future<T> executeFroomTransaction<T>(
    Future<T> Function() action, {
    String? databaseName,
    TransactionDefinition definition = const TransactionDefinition(),
  }) async {
    final froomDb = getFroomDatabase(databaseName);
    if (froomDb == null) {
      throw StateError(
          'Froom数据库未注册: ${databaseName ?? TransactionManager._defaultDatabaseName}');
    }

    return execute(
      _FroomActionCallback(action),
      definition: definition,
      databaseName: databaseName,
    );
  }
}

/// 简单事务回调实现
class _SimpleTransactionCallback<T> implements TransactionCallback<T> {
  final Future<T> Function(sqflite.Transaction txn) _action;

  _SimpleTransactionCallback(this._action);

  @override
  Future<T> doInTransaction(TransactionStatus status) async {
    final txn = status.transaction;
    if (txn == null) {
      throw StateError('事务对象不可用');
    }
    return _action(txn);
  }
}

/// 函数事务回调实现
class _FunctionTransactionCallback<T> implements TransactionCallback<T> {
  final Future<T> Function(TransactionStatus status) _action;

  _FunctionTransactionCallback(this._action);

  @override
  Future<T> doInTransaction(TransactionStatus status) {
    return _action(status);
  }
}

/// Froom动作回调实现
class _FroomActionCallback<T> implements TransactionCallback<T> {
  final Future<T> Function() _action;

  _FroomActionCallback(this._action);

  @override
  Future<T> doInTransaction(TransactionStatus status) {
    return _action();
  }
}
